<template>
  <div class="page-container new-flow">
    <b-breadcrumb :items="breadcrumb"/>
    <!-- 提示窗 -->
    <b-alert show :variant="error.color" :show="error.countDown" dismissible @dismiss-count-down="countDown"
             class="text-center">
      <p>{{error.msg}}</p>
      <b-progress variant="warning" :max="3" :value="error.countDown" height="4px"></b-progress>
    </b-alert>
    <!-- 提示窗end -->
      <div class="toolbar">
        <div class="toolbar-left">
          <b-form-group horizontal
                        :label-cols="4"
                        label="流程名称："
          >
            <b-form-input v-model="flowData.name"
                          class="mb-3"
                          :class="{'is-invalid': !addFormOption.isNamed }"
            >
            </b-form-input>
            <p v-show="!addFormOption.isNamed" class="input-help is-invalid">流程名不能为空</p>
          </b-form-group>
        </div>
        <div class="toolbar-right">
          <b-button @click="workFlowAdd" variant="primary" :disabled="!addFormOption.isNamed">提交</b-button>
        </div>
      </div>
      <div class="main">
        <div class="org-container">
          <orgchart v-model="flowData.nodeParam" :data="flowData.nodeParam" :editNode="getEditNode" ref="orgchart"
                    :onDropEnd="onDrop"></orgchart>
        </div>
        <div class="list-container nodes">
          <div class="node list-group-item" v-for="item in nodeData" :data-source="JSON.stringify(item)"
               draggable="true"
               @dragstart="onDragStart" @dragend="onDragEnd">
            <div class="tittle">{{item.objName}}</div>
          </div>
          <b-pagination class="mt-5 mx-auto" size="md" :total-rows="pagination.totalRows" v-model="pagination.page"
                        :per-page="pagination.rows">
          </b-pagination>
        </div>
      </div>

      <!-- 增加节点弹窗修改数据 -->
      <b-modal id="addNode" title="新增节点" :lazy="true" ok-title="提交" @hide="onHidden" @ok="addNode" cancel-title="取消"
               centered>
        <div class="container">
          <b-form @submit.prevent="workFlowAdd">
            <b-form-group horizontal
                          :label-cols="3"
                          label="节点类型："
            >
              <b-form-select v-model="addFormData.nodeType"
                             :options="addFormOption.nodeTypeOption"
                             class="mb-3"
                             name="nodeType"
                             v-validate="'required'"
                             :class="{'is-invalid': errors.has('nodeType') }"
              >
              </b-form-select>
              <p v-show="errors.has('nodeType')" class="input-help is-invalid">{{ errors.first('nodeType') }}</p>
            </b-form-group>
            <b-form-group horizontal
                          :label-cols="3"
                          label="节点参数："
            >
              <b-form-input v-model="addFormData.nodeParam" class="mb-3">
              </b-form-input>
            </b-form-group>
            <b-form-group horizontal
                          :label-cols="3"
                          label="关联顺序："
              >
              <b-form-input v-model="addFormData.relation"
                            class="mb-3"
                            name="relation"
                            v-validate="'numeric'"
                            :class="{'is-invalid': errors.has('relation') }"
              >
                </b-form-input>
                <p v-show="errors.has('relation')" class="input-help is-invalid">{{ errors.first('relation') }}</p>
            </b-form-group>
          </b-form>
        </div>
      </b-modal>
  </div>
</template>

<script>
  import { findAllExpert } from 'api/business/node'
  import { workFlowAdd } from 'api/business/workflow'
  import { each } from 'utils/dom.js'
  import orgchart from 'components/drag-orgchart/drag-orgchart.vue'
  import 'components/drag-orgchart/orgchart.min.css'

  export default {
    components: {
      orgchart
    },
    data () {
      return {
        breadcrumb: [
          {
            text: '业务配置'
          }, {
            text: '流程配置',
            to: '/business/workflow',
            replace: true
          }, {
            text: '新增流程'
          }
        ],
        error: {
          msg: '',
          countDown: 0,
          color: 'danger'
        },
        addFormData: {
          nodeType: '',
          nodeParam: '',
          relation: ''
        },
        addFormOption: {
          nodeTypeOption: [
            {text: '请选择', value: ''},
            {text: '同步', value: 1},
            {text: '异步', value: 2},
            {text: '优先', value: 3},
            {text: '定时', value: 4},
            {text: '超时', value: 5},
            {text: '条件', value: 6}
          ],
          nodeParamOption: [
            {text: '请选择', value: ''},
            {text: '定时周期(ms)', value: 4},
            {text: '超时时间(ms)', value: 5},
            {text: '条件表达式', value: 6}
          ],
          isNamed: true
        },
        flowData: {
          'name': '',
          'nodeParam': {}
        },
        nodeData: [],
        pagination: {
          page: 1, // 页码
          totalRows: 0,   // 总条数
          rows: 10        // 每页条数
        },
        nodeOnDrag: {
          node: '',
          source: ''
        },
        isAdd: true
      }
    },
    watch: {
      'pagination.page': function (currentVal) {
        this.findAll({page: this.pagination.page - 1})
      },
      'flowData.name': function (currentVal) {
        this.validate()
      }
    },
    methods: {
      /* 弹窗提示 */
      tipSuccess (text, time) {
        this.error = {
          msg: text,
          countDown: time,
          color: 'success'
        }
      },
      tipError (text, time) {
        this.error = {
          msg: text,
          countDown: time,
          color: 'danger'
        }
      },
      countDown (count) {
        this.error.countDown = count
      },
      /* 弹窗提示end */
      // 查询
      findAll (data) {
        var me = this
        findAllExpert(data).then(function (res) {
          if (res.code === 100000) {
            var data = res.data
            me.nodeData = data.content
            me.pagination.totalRows = data.totalElements
          } else {
            console.log(res)
            me.tipError(res.msg, 3)
          }
        })
      },
      // 新增流程
      workFlowAdd () {
        var me = this
        if (!me.validate()) return
        me.flowData.nodeParam.name = me.flowData.name
        me.flowData.nodeParam.id = null
        workFlowAdd(this.flowData.nodeParam).then(function (res) {
          if (res.code === 100000) {
            me.tipSuccess(res.msg, 3)
            setTimeout(function () {
              me.$router.push('/business/workflow')
            }, 3000)
          } else {
            me.tipError(res.msg, 3)
          }
        })
      },
      // 新增流程节点
      addNode (e) {
        e.preventDefault()
        var data = this.addFormData
        var item = JSON.parse(this.nodeOnDrag.node.getAttribute('data-source'))
        this.$validator.validateAll().then((result) => {
          if (result) {
            each(data, function (key, value) {
              item[key] = value
              data[key] = ''
            })
            this.nodeOnDrag.node.setAttribute('data-source', JSON.stringify(item))
            this.$refs.orgchart.triggerInput()
            this.$root.$emit('bv::hide::modal', 'addNode')
          }
        })
      },
      // 节点信息编辑弹窗关闭时执行
      onHidden (evt) {
        if (evt.isOK === 'ok' || evt.isOK === null) {
          return
        } else if (this.isAdd) {
          this.nodeOnDrag.node.parentNode.removeChild(this.nodeOnDrag.node)
          this.$refs.orgchart.triggerInput()
        }
        this.isAdd = true
      },
      // 编辑节点信息
      editNode (id) {
        var me = this
        var data = this.addFormData
        var nodeParam = this.flowData.nodeParam
        var item
        each(nodeParam, function (key, val) {
          if (val.id === id) {
            item = nodeParam[key]
            me.initParent(id)
          }
        })
        each(data, function (key) {
          data[key] = item[key]
        })
        this.$root.$emit('bv::show::modal', 'addNode')
        this.isAdd = false
      },
      // 初始化父节点下拉框选项
      initParent (id) {
        var nodeParam = this.flowData.nodeParam
        this.addFormOption.parentIdOption = []
        var parentIdOption = this.addFormOption.parentIdOption
        each(nodeParam, function (key, val) {
          parentIdOption[key] = {}
          parentIdOption[key]['text'] = nodeParam[key]['obj']
          parentIdOption[key]['value'] = nodeParam[key]['id']
        })
        if (id || id === 0) {
          each(parentIdOption, function (key, val) {
            if (val.value === id) {
              parentIdOption.splice(key, 1)
              return false
            }
          })
        }
      },
      // 开始拖动时
      onDragStart (e) {
        this.nodeOnDrag.node = e.target.cloneNode(true)
        var rootEle = document.getElementById('chart-container')
        Array.from(rootEle.querySelectorAll('.node')).forEach(function (node) {
          node.classList.add('allowedDrop')
        })
        this.$refs.orgchart.orgchart.dragged = this.nodeOnDrag.node
      },
      // 拖动结束时
      onDragEnd (e) {
        var rootEle = document.getElementById('chart-container')
        if (!this.$refs.orgchart.orgchart.isNull) {
          Array.from(rootEle.querySelectorAll('.allowedDrop')).forEach(function (el) {
            el.classList.remove('allowedDrop')
          })
        }
      },
      // 放置时
      onDrop () {
        this.$root.$emit('bv::show::modal', 'addNode')
      },
      // 获取正在编辑的节点的信息
      getEditNode (e) {
        this.isAdd = false
        this.nodeOnDrag.node = e
        var source = JSON.parse(e.getAttribute('data-source'))
        var data = this.addFormData
        each(data, function (key) {
          data[key] = source[key]
        })
        this.$root.$emit('bv::show::modal', 'addNode')
      },
      // 验证
      validate () {
        if (this.flowData.name === null || this.flowData.name === '') {
          this.addFormOption.isNamed = false
        } else {
          this.addFormOption.isNamed = true
        }
        return this.addFormOption.isNamed
      }
    },
    mounted () {
      var me = this
      this.$root.eventHub.$on('error', function (e) {
        me.tipError(e, 3)
      })
    },
    created () {
      this.findAll()
    }
  }
</script>

<style lang="scss">
  .new-flow {
    .main {
      display: flex;
      justify-content: space-around;
    }
    .list-container {
      width: 20%;
    }

    .list-group {
      min-height: 30px;
      padding: 10px;
      border: 1px solid #494949;
      border-radius: 5px;
    }
    .modal-footer {
      justify-content: center;
      .btn {
        margin-left: 2rem;
      }
    }
  }
  .org-container {
    max-width: 1100px;
    max-height: 590px;
    overflow: hidden;
  }
  @media screen and (max-width: 1366px) {
    .org-container {
      max-width: 574px;
      overflow: hidden;
    }
  }

</style>
